const direction = 1; //-1往左，1往右
const distance = 45;
const boxWidth = 100;
const boxInfoDis = 5;
const movex = 60;

const configData = {
  width: 1500,
  height: 900,
  boxNum: 6,
  duanziDis: distance, //端子间距,可以修改
  duanziNum: 4, //端子个数
  boxHeight: 0 * distance + 120, //箱盒高度，参数可修改
  boxWidth: boxWidth, //箱盒宽度,可以修改
  boxInfoDis: boxInfoDis, //箱盒信息高度,可以修改
  boxInfoLine: {},
  duanziList: [
    {
      name: "",
      position: [boxWidth / 2, boxInfoDis * 3 + 0 * distance], //端子坐标
      path: [
        [-movex / 2, boxInfoDis * 3 + 0 * distance],
        [boxWidth + movex / 2, boxInfoDis * 3 + 0 * distance],
      ],
    },
  ],
  boxMove: [(movex + boxWidth) * direction, 0],
};

function init() {
  svgContainer = d3
    .select("#svg-meta")
    .append("svg")
    .attr("id", "svg-meta2")
    .attr("width", configData.width)
    .attr("height", configData.height)
    .attr("style", "border:1px solid red");
  rectsGroup = svgContainer.append("g").attr("class", "rects-group");
  fit();
}
function fit() {
  let width =
    configData.boxNum * configData.boxWidth + (configData.boxNum + 3) * movex;
  let height = configData.duanziNum * configData.duanziDis;
  let scaleW = configData.width / width;
  let scaleH = configData.height / height;
  let scale = scaleW < scaleH ? scaleW : scaleH;

  let offsetX =
    direction < 0
      ? configData.boxNum * configData.boxWidth + configData.boxNum * movex
      : boxWidth * 2 + movex * 2;
  let offsetY = (configData.height - height) / 2;
  let zoom = d3
    .zoom()
    .scaleExtent([0.1, 100])
    .on("zoom", function () {
      scale = d3.event.transform.k;
      offsetX = d3.event.transform.x;
      offsetY = d3.event.transform.y;
      if (!isNaN(d3.event.transform.k))
        rectsGroup.attr("transform", d3.event.transform);
    });

  let pathover = svgContainer.call(zoom);
  pathover
    .transition()
    .duration(400)
    .call(
      zoom.transform,
      d3.zoomIdentity.translate(offsetX, offsetY).scale(scale)
    );
}

// 原始数据预处理
function handleData(dataList) {
  // 分线盘
  let dz_list = dataList.fxp_dz_lst;
  let boxinfo = {
    name: dataList.fxp_name + dataList.fxp_info,
    cable_info: "",
  };
  preHandle(dz_list, [0, 0], boxinfo);
  // 组合柜
  let pa_list = dataList.fxp_parent_box.zhg_duanzi_lst;
  let move = [(boxWidth + movex) * -1 * direction, 0];
  let zhginfo = {
    name: dataList.fxp_parent_box.zhg_name + dataList.fxp_parent_box.zhg_info,
    cable_info: "",
  };
  preHandle(pa_list, move, zhginfo);

  // 子箱盒
  dataList.fxp_to_box.child_box_lst.push({
    begin_box_name: "",
    box_info: dataList.fxp_info,
    box_name: dataList.fxp_name,
    cable_info: "",
    dz_lst: dataList.fxp_dz_lst,
  });

  recursion(dataList.fxp_to_box.child_box_lst, dataList.fxp_name, 1, 1);
}

function recursion(list, parentName, num, ynum) {
  let realList = list;
  // 横向偏移
  let n = num;

  let child = realList.filter((item) => item.begin_box_name == parentName);
  let parent = realList.filter((i) => i.box_name == parentName)[0];
  // 计算上下偏移
  let childList = child.map((item) => {
    let up =
      ynum +
      parent.dz_lst.findIndex(
        (ele) =>
          ele.next_box + "" + ele.next_dz ==
          item.box_name + "" + item.dz_lst[0].dz_name
      );
    return { ...item, ynum: up };
  });
  // 根据计算结果绘制子箱盒
  childList.forEach((item) => {
    preHandle(
      item.dz_lst,
      [(boxWidth + movex) * direction * n, item.ynum * configData.duanziDis],
      {
        name: item.box_name + item.box_info,
        cable_info: item.cable_info,
      }
    );
  });
  n++;
  // 遍历每个子箱盒
  childList.forEach((item) => {
    recursion(realList, item.box_name, n, item.ynum);
  });
}

// 图形绘制数据
function preHandle(dz_lst, move, boxinfo) {
  configData.boxInfoLine = {};
  if (!Array.isArray(dz_lst)) return;
  configData.duanziNum = dz_lst.length;
  configData.boxHeight =
    (configData.duanziNum - 1) * distance + boxInfoDis * 2 + 20;
  configData.boxInfoLine[boxinfo.name] = [
    [0, 1 * boxInfoDis],
    [boxWidth, 1 * boxInfoDis],
  ];
  // Object.keys(boxinfo).forEach((i, index) => {
  //   configData.boxInfoLine[boxinfo[i]] = [
  //     [0, (1 + index) * boxInfoDis],
  //     [boxWidth, (1 + index) * boxInfoDis],
  //   ];
  // });
  configData.boxMove = [move[0], move[1]];
  configData.duanziList = dz_lst.map((item, index) => {
    return {
      ...item,
      name: item.dz_name,
      position: [boxWidth / 2, boxInfoDis * 3 + index * distance],
      path: [
        [-movex / 2, boxInfoDis * 3 + index * distance],
        [boxWidth + movex / 2, boxInfoDis * 3 + index * distance],
      ],
    };
  });
  renderRects("s" + boxinfo.name, boxinfo.cable_info);
}
function renderRects(id, name) {
  let line_generator = d3.line();

  rectsGroup
    .append("g")
    .attr(
      "transform",
      `translate(${configData.boxMove[0]}, ${configData.boxMove[1]})`
    )
    .attr("id", id);
  // 画矩形,箱盒
  rectsGroup
    .select(`#${id}`)
    .append("g")
    .attr("id", "reacts")
    .append("rect")
    .attr("width", configData.boxWidth)
    .attr("height", configData.boxHeight)
    .attr("x", 0)
    .attr("y", 0)
    .attr("stroke", "black")
    .attr("fill", "transparent");
  //画cable_info
  rectsGroup
    .select(`#${id}`)
    .append("text")
    .text(name)
    .attr(
      "x",
      direction > 0
        ? (movex / 2) * direction + boxWidth
        : (movex / 2) * direction
    )
    .attr("y", -5)
    .attr("font-size", "10px")
    .attr("fill", "red");
  //画两条线，箱盒信息

  Object.keys(configData.boxInfoLine).forEach((info, index) => {
    // rectsGroup
    //   .select(`#${id}`)
    //   .select("#reacts")
    //   .append("path")
    //   .attr("d", line_generator(configData.boxInfoLine[info]));
    rectsGroup
      .select(`#${id}`)
      .select("#reacts")
      .append("text")
      .text(info)
      .attr("dx", boxWidth / 2)
      .attr("dy", index * boxInfoDis - 5)
      .attr("font-size", "10px")
      .attr("fill", "red");
  });

  //画线，线束及线束名称
  configData.duanziList.forEach((pat) => {
    let position =
      direction == 1
        ? [pat.path[1][0], pat.path[0][1] - 5]
        : [pat.path[0][0], pat.path[0][1] - 5];
    rectsGroup
      .select(`#${id}`)
      .select("#reacts")
      .append("path")
      .attr("d", line_generator(pat.path))
      .attr("class", "xianshu");
    rectsGroup
      .select(`#${id}`)
      .select("#reacts")
      .append("text")
      .text(pat.next_xs)
      .attr("dx", position[0])
      .attr("dy", position[1])
      .attr("font-size", "10px")
      .attr("fill", "red");
  });
  //设置线的外观，箱盒颜色
  rectsGroup
    .select(`#${id}`)
    .selectAll("path")
    .attr("stroke", "black")
    .attr("stroke-width", "1px");
  renderCircle(id);
}

function renderCircle(id) {
  // 画点，端子
  rectsGroup
    .select(`#${id}`)
    .select("#reacts")
    .append("g")
    .attr("class", "point-circle")
    .selectAll("circle")
    .data(configData.duanziList)
    .join("circle")
    .attr("class", "points")
    .attr("id", (d) => d.name)
    .attr("cx", (d) => d.position[0])
    .attr("cy", (d) => d.position[1])
    .attr("fill", "blue")
    .attr("r", 2);

  // 在点上画文字，端子名称
  rectsGroup
    .select(`#${id}`)
    .select("#reacts")
    .attr("class", "point-text")
    .append("g")
    .selectAll()
    .data(configData.duanziList)
    .join("text")
    .text(function (d) {
      return d.name;
    })
    .attr("dx", (d) => d.position[0] - 8)
    .attr("dy", (d) => d.position[1] - 5)
    .attr("font-size", "10px")
    .attr("fill", "red");
}
